package 变长滑动窗口1

func maximumLengthSubstring(s string) (ans int) {
	charCount := map[byte]int{}
	n := len(s)
	left := 0
	right := -1
	for left < n {
		if left > 0 {
			charCount[s[left-1]]-- // 正确：减的是上一个左边界的字符（s[left-1]）
			// 可选优化：若计数为0，从map中删除（不影响结果，仅节省空间）
			if charCount[s[left-1]] == 0 {
				delete(charCount, s[left-1])
			}
		}
		for right+1 < n && charCount[s[right+1]] < 2 {
			charCount[s[right+1]]++
			right++
		}
		currentLen := right - left + 1
		ans = max(ans, currentLen)
		left++
	}
	return
}

/// maximumLengthSubstring 寻找字符串中每个字符最多出现2次的最长子串长度
//// 题目要求：子串中每个字符的出现次数不能超过2次，返回满足条件的最长子串长度
//func maximumLengthSubstring(s string) (ans int) {
//    // cnt：记录每个小写字母的出现次数（索引0对应'a'，1对应'b'，...，25对应'z'）
//    // 用数组而非哈希表，因为输入是小写字母，数组访问更快（O(1)时间）
//    cnt := [26]int{}
//    left := 0 // 滑动窗口的左边界，窗口范围为 [left, i]（闭区间）
//
//    // i：滑动窗口的右边界，遍历字符串中的每个字符
//    for i, b := range s {
//        // 将当前字符转换为0-25的索引（'a'→0，'b'→1，...，'z'→25）
//        // 便于在cnt数组中定位对应的计数位置
//        b -= 'a'
//
//        // 1. 扩展右边界：将当前字符加入窗口，更新其出现次数
//        cnt[b]++
//
//        // 2. 收缩左边界：如果当前字符的出现次数超过2次，需要移动左指针，直到该字符次数≤2
//        // （因为窗口内不能有任何字符出现超过2次，当前字符超了，必须缩小窗口）
//        for cnt[b] > 2 {
//            // 左边界字符离开窗口，减少其计数
//            cnt[s[left]-'a']-- // s[left]是左边界字符，转换为0-25索引后更新计数
//            left++             // 左指针右移，缩小窗口
//        }
//
//        // 3. 更新最长子串长度：当前窗口 [left, i] 是有效的（所有字符≤2次）
//        // 计算窗口长度（i - left + 1），与历史最大值ans比较并更新
//        ans = max(ans, i-left+1)
//    }
//
//    return ans
//}
